package com.lhn.spring5.service;

import com.lhn.spring5.dao.AccountDao;
import com.lhn.spring5.entity.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 账户业务处理
 *
 * @author lhn
 * @date 2022/01/06 14:28
 * @since 1.0.0
 **/
/**
 Transactional 可选参数
    1.propagation:事务传播行为,默认是:REQUIRED
        1.1 多事务方法(对数据库表数据进行变化的操作)直接进行调用,这个过程中事务是如何进行管理的
    2.isolation:事务隔离级别
        1.1 事务有特性称为隔离性,多事务操作之间不会产生影响.
        1.2 不考虑隔离性会有三个读问题:脏读,不可重复读,虚(幻)读
            1.2.1 脏读:一个未提交事务读到另一个未提交事务的数据
            1.2.2 不可重复读:一个未提交事务读到另一提交事务的修改数据
            1.2.3 幻读:一个未提交事务读到另一提交事务的提交数据
    3.timeout:超时时间
        1.1 事务需要在一定的时间内进行提交,如果不提交则进行回滚.
        1.2 默认是 -1,没有超时时间.可以设置单位为秒.
    4.readOnly:是否是只读
        1.1 读:查询操作,写:增删改操作
        1.2 readOnly 默认是 false.
        1.3 设置为 ture 后只能做查询的操作.
    5.rollbackFor:回滚
        1.1 出现哪些异常后进行回滚
    6.rollbackForClassName:
    7.noRollbackFor:不回滚
        1.1 出现哪些异常后不进行回滚
    8.noRollbackForClassName
 * */
@Service
@Transactional
public class AccountService {

    @Autowired
    private AccountDao accountDao;


    /**
     * 账户增加
     *
     * @param account 账户信息
     */
    public void addAccount(Account account){
        accountDao.addAccount(account);
    }

    /**
     * 账户减少
     *
     * @param account 账户信息
     * */
    public void reduceAccount(Account account){
        accountDao.reduceAccount(account);
    }

    /**
     *  编程式事务管理和声明式事务管理
     *    声明式事务管理
     *      1.基于注解的方式
     *      2.基于xml配置文件的方式
 *        在 Spring 进行事务管理,底层使用 AOP 原理
 *        Spring 事务管理 API
     *        1.提供一个接口,事务管理器.
     *
     * */
    public void accountMoney() {
        // 1.开启事务

        // 2.进行业务处理
        //try {
            Account mary = new Account(1, "mary", 100);
            this.reduceAccount(mary);
            int i = 0 / 0;
            Account lucy = new Account(1, "lucy", 100);
            this.addAccount(lucy);
        //    3.无异常提交事务
        //} catch (Exception e) {
        //    // 4.有异常进行回滚
        //    e.printStackTrace();
        //}

    }
}